package net.gdface.bean.jdk.descriptor;

import java.beans.IntrospectionException;
import java.lang.reflect.Method;
import java.util.Map;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * 实现对{@link Map}实例的属性封装
 * @author guyadong
 * @since 2.7.0
 */
public class MapPropertyDescriptor extends BaseNoStandardPropertyDescriptor{

	private final Method readMethod;
	private final Method writeMethod;
	private final Class<?> propertyType;
	public MapPropertyDescriptor(Class<?> propertyType, String name)
			throws IntrospectionException {
		/** 将属性名中的.替换为_,以避免对nested name解析出错 */
		super(checkNotNull(name,"field is null").replace(".", "_"), null, null);
		setDisplayName(name);
		this.propertyType = null == propertyType ? Object.class : propertyType;
		try {
			readMethod = getClass().getMethod("readMethod", Object.class,String.class);
			writeMethod = getClass().getMethod("writeMethod", Object.class,String.class,Object.class);
		} catch (RuntimeException e) {
            throw e;
        }catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 字段读取方法实现
	 * @param bean 读取目标对象
	 * @param name 字段名
	 * @return 字段值
	 */
	@SuppressWarnings("rawtypes")
	public static Object readMethod(Object bean,String name){
		if(bean instanceof Map){
			return ((Map)bean).get(name);
		}
		return null;
	}
	/**
	 * 字段写入方法实现
	 * @param bean 写入目标对象
	 * @param name 字段名
	 * @param value 要写入的值
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static void writeMethod(Object bean,String name,Object value){
		if(bean instanceof Map){
			Map map = (Map)bean;
			if(null == value){
				map.remove(name);
			}else {
				map.put(name, value);
			}
		}
	}

	@Override
	public Method getReadMethod() {
		return readMethod;
	}

	@Override
	public Method getWriteMethod() {
		return writeMethod;
	}

	@Override
	public Class<?> getPropertyType() {
		return propertyType;
	}
	@Override
	public boolean isWritable(Object object){
		return true;
	}
}
